#include "cnckernel.h"
#include <iostream>

class CooperativeMode : public cnc::base::CooperativeTask
{
protected:
	static const char *modeName_[];
	cnc::base::KernelSetup *coordinator_;
	const cnc::base::OperationModeID thisMode_;
	int menu()
	{
		int option;
		for (int i = 0; i < 8; i++)
			std::cout << "\t" << i + 1 << ". " << modeName_[i] << std::endl;
		std::cout << "\t9. Salir" << std::endl;
		std::cin >> option;
		return option;
	}
public:
	CooperativeMode(cnc::base::OperationModeID thisMode) : thisMode_(thisMode)
	{
		cnc::base::CNCKernel *cncKernel = cnc::base::getCNCKernel();
		coordinator_ = cncKernel->getKernelSetup();
	}
	virtual void start()
	{
		std::cout << "Iniciar " << modeName_[thisMode_] << std::endl;
	}
	virtual bool execute()
	{
		std::cout << "---" << modeName_[thisMode_] << "---" << std::endl;
		cnc::base::OperationModeID nextMode = static_cast<cnc::base::OperationModeID>(menu() - 1);
		if (nextMode != 8) {
			std::cout << "Elegiste " << modeName_[nextMode] << std::endl;
			if (nextMode != thisMode_) {
				coordinator_->selectMode(nextMode);
				return false;
			}
			return true;
		}
		return false;		
	}
	virtual void stop()
	{
		std::cout << "Detener " << modeName_[thisMode_] << std::endl;
	}
};

const char *CooperativeMode::modeName_[] = {
	"Modo de configuración",
	"Modo IMD",
	"Modo impulso",
	"Modo posicionamiento",
	"Modo manivela",
	"Modo memoria",
	"Modo administrador de archivos",
	"Modo edición"
};

class BackgroundTask : public cnc::base::CooperativeTask
{
public:
	virtual void start()
	{
		std::cout << "Iniciar tarea de segundo plano." << std::endl;
	}
	virtual bool execute()
	{
		std::cout << "Ejecutar tarea de segundo plano." << std::endl;
	}
	virtual void stop()
	{
		std::cout << "Detener tarea de segundo plano." << std::endl;
	}
};

int main()
{
	cnc::base::CNCKernel *cncKernel = cnc::base::getCNCKernel();
	if (cncKernel == 0) {
		std::cout << "Error al cargar el núcleo." << std::endl;
		return 1;
	}
	cnc::base::KernelSetup *setup = cncKernel->getKernelSetup();
	CooperativeMode setupMode(cnc::base::OPMODE_SETUP);
	CooperativeMode mdiMode(cnc::base::OPMODE_MDI);
	CooperativeMode jogMode(cnc::base::OPMODE_JOG);
	CooperativeMode rapidMode(cnc::base::OPMODE_RAPID);
	CooperativeMode handwheelMode(cnc::base::OPMODE_HANDWHEEL);
	CooperativeMode memoryMode(cnc::base::OPMODE_MEMORY);
	CooperativeMode tapeMode(cnc::base::OPMODE_TAPE);
	CooperativeMode editMode(cnc::base::OPMODE_EDIT);
	BackgroundTask bgTask;
	setup->addTask(&bgTask);
	setup->addMode(cnc::base::OPMODE_SETUP, &setupMode);
	setup->addMode(cnc::base::OPMODE_MDI, &mdiMode);
	setup->addMode(cnc::base::OPMODE_JOG, &jogMode);
	setup->addMode(cnc::base::OPMODE_RAPID, &rapidMode);
	setup->addMode(cnc::base::OPMODE_HANDWHEEL, &handwheelMode);
	setup->addMode(cnc::base::OPMODE_MEMORY, &memoryMode);
	setup->addMode(cnc::base::OPMODE_TAPE, &tapeMode);
	setup->addMode(cnc::base::OPMODE_EDIT, &editMode);
	cnc::base::KernelControl *control = cncKernel->getKernelControl();
	control->start();
	control->execute();
	control->stop();
	return 0;
}

